package org.jeecg.modules.medication_order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.boot.starter.rabbitmq.client.RabbitMqClient;
import org.jeecg.common.base.BaseMap;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.constant.rabbitConstant;
import org.jeecg.modules.medication.entity.MedicationShop;
import org.jeecg.modules.medication.mapper.MedicationShopMapper;
import org.jeecg.modules.medication_order.entity.MedicationOrder;
import org.jeecg.modules.medication_order.mapper.MedicationOrderMapper;
import org.jeecg.modules.medication_order.service.IMedicationOrderService;
import org.jeecg.modules.medication_order.vo.MedicationOrderVo;
import org.jeecg.modules.medication_order.entity.MedicationOrderDetail;
import org.jeecg.modules.medication_order_detail.mapper.MedicationOrderDetailMapper;
import org.jeecg.modules.medication_order_detail.service.IMedicationOrderDetailService;
import org.jeecg.modules.nurse_user.entity.NurseUser;
import org.jeecg.modules.nurse_user.mapper.NurseUserMapper;
import org.jeecg.modules.nurse_user_orders.entity.NurseUserOrders;
import org.jeecg.modules.nurse_user_orders_refund.entity.NurseUserOrdersRefund;
import org.jeecg.modules.wechat.service.WechatPaymentService;
import org.jeecg.modules.wechat.utils.WXPaySignatureCertificateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Description: 药房订单
 * @Author: jeecg-boot
 * @Date:   2025-06-20
 * @Version: V1.0
 */
@Service
public class MedicationOrderServiceImpl extends ServiceImpl<MedicationOrderMapper, MedicationOrder> implements IMedicationOrderService {
    @Autowired
    private NurseUserMapper nurseUserMapper;

    @Autowired
    private MedicationShopMapper medicationShopMapper;

    @Autowired
    private WechatPaymentService wechatPaymentService;

    @Autowired
    private IMedicationOrderDetailService MedicationOrderDetailService;

    @Autowired
    private MedicationOrderMapper medicationOrderMapper;

    @Autowired
    private MedicationOrderDetailMapper medicationOrderDetailMapper;

    @Autowired
    private RabbitMqClient rabbitMqClient;

    @Value("${wechat.nurse.expiry-time:}")
    private Integer expiryTime;

    @Value("${wechat.nurse.appid:}")
    private String APP_ID;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseMap addByWeChat(MedicationOrderVo medicationOrderVo,String mchId) {

        NurseUser nurseUser = nurseUserMapper.selectById(medicationOrderVo.getUserId());

        if (nurseUser == null) {
            throw new JeecgBootException("未查询到用户");
        }

        BaseMap map = new BaseMap();


        String orderId = UUIDGenerator.generate();

        BigDecimal amt = new BigDecimal(0);

        List<MedicationOrderDetail> medicationOrderDetailList = new ArrayList<>();
        MedicationOrder medicationOrder = new MedicationOrder();
        String flag="0";
        for (MedicationOrderDetail entity : medicationOrderVo.getMedicationOrderDetails()) {
            MedicationOrderDetail medicationOrderDetail = new MedicationOrderDetail();
            MedicationShop medicationShop = medicationShopMapper.selectById(entity.getGoodsId());
            if("1".equals(medicationShop.getIsAuth())){
                flag="1";
            }
            if (medicationShop == null) {
                throw new JeecgBootException("未查询到商品详情");
            }

            medicationOrderDetail.setId(null);
            medicationOrderDetail.setNum(entity.getNum());
            medicationOrderDetail.setGoodsId(entity.getGoodsId());
          //  BigDecimal tprice=medicationShop.getPrice().multiply(new BigDecimal(entity.getNum()));
            if(oConvertUtils.isEmpty(entity.getPrice()) || entity.getPrice().equals(0)){
                entity.setPrice(medicationShop.getPrice());
            }
            if(oConvertUtils.isEmpty(entity.getNum())){
                entity.setNum(1.00);
            }

            BigDecimal tprice=entity.getPrice().multiply(new BigDecimal(entity.getNum()));
            medicationOrderDetail.setTotalPrice(tprice);
            medicationOrderDetail.setOrderId(orderId);
           // medicationOrderDetail.setPrice(medicationShop.getPrice());
            medicationOrderDetail.setPrice(entity.getPrice());
            medicationOrderDetail.setGoodsName(medicationShop.getTypeName());
            medicationOrderDetailList.add(medicationOrderDetail);
            amt = amt.add(tprice);

        }
        amt=amt.add(medicationOrderVo.getExtraFees());
        medicationOrder.setCode(orderId);
        medicationOrder.setTotalPrice(String.valueOf(amt));
        medicationOrder.setStatus("1");
        medicationOrder.setIsAuth(flag);  //有需要审核的商品就审核
        medicationOrder.setUserId(nurseUser.getId());
        medicationOrder.setUserName(nurseUser.getName());
        medicationOrder.setOutTradeNo(orderId);
        medicationOrder.setOrderText(medicationOrderVo.getOrderText());
        medicationOrder.setMchId(mchId);
        medicationOrder.setFamilyId(medicationOrderVo.getFamilyId());
        medicationOrder.setFamilyName(medicationOrderVo.getFamilyName());
        medicationOrder.setSysOrgCode(medicationOrderVo.getSysOrgCode());
        Long total = amt.multiply(BigDecimal.valueOf(100)).longValue();

        map.put("total", total);
        map.put("description", medicationOrder.getOrderText());
        map.put("out_trade_no", medicationOrder.getOutTradeNo());
        map.put("openid", nurseUser.getOpenid());
        map.put("type","1");

        try {
            map = wechatPaymentService.weChatDoUnifiedOrder(map,mchId);

        } catch (Exception e) {
            e.printStackTrace();
        }

        if (!map.get("code").equals(200)) {
            throw new JeecgBootException("微信下单失败！！！！" + map.toString());
        }

        medicationOrder.setPrepayid(map.get("prepayid"));

        medicationOrderMapper.insert(medicationOrder);

        MedicationOrderDetailService.saveBatch(medicationOrderDetailList);

        map.put("out_trade_no", orderId);

        Integer expiry_time = 1000 * expiryTime;

        rabbitMqClient.sendMessage(rabbitConstant.DELAY_QUEUE_ORDER_NAME, map, expiry_time);
        //log.info("订单编号：[{}] 进入延迟队列...", orderId);
        return map;
    }

    @Override
    public BaseMap payByWeChat(String out_trade_no) {

        BaseMap map = new BaseMap();

        MedicationOrder medicationOrder = medicationOrderMapper.selectById(out_trade_no);

        if (oConvertUtils.isEmpty(medicationOrder)) {
            throw new JeecgBootException("未查询到订单");
        }
        if (!medicationOrder.getStatus().equals("1")) {
            throw new JeecgBootException("未查询到待支付订单");
        }

        try {
            map.put("mchId", medicationOrder.getMchId());
            map.put("prepayid", medicationOrder.getPrepayid());
            map = WXPaySignatureCertificateUtil.jsApiPay(map, APP_ID);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return map;
    }

    @Override
    public MedicationOrder successPay(MedicationOrder medicationOrder) {

        List<MedicationOrderDetail> MedicationOrderDetail = medicationOrderDetailMapper.selectList(new QueryWrapper<MedicationOrderDetail>().eq("order_id", medicationOrder.getOutTradeNo()));

        if (MedicationOrderDetail == null) {
            return null;
        }
        if (MedicationOrderDetail.size() == 0) {
            return null;
        }

        medicationOrder.setStatus("2");

        medicationOrderMapper.updateById(medicationOrder);

        return medicationOrder;
    }

    @Override
    public List<Map<String, Object>> listByWeChat(String beginDate, String endDate,  String userId, String status) {
        return medicationOrderMapper.listByWeChat(userId);
    }

    @Override
    public void payNotify(HttpServletRequest request, String mchId) {

        BaseMap map = wechatPaymentService.weChatNotificationHandler(request,mchId);

        if (!map.get("code").equals(200)) {
            return;
        }
        MedicationOrder medicationOrder = medicationOrderMapper.selectOne(new QueryWrapper<MedicationOrder>().eq("out_trade_no", map.get("out_trade_no")));

        if (oConvertUtils.isEmpty(medicationOrder)) {
            return;
        }

        if (medicationOrder.getStatus().equals("2") ) {
            return;
        }
        successPay(medicationOrder);
    }
    @Override
    public BaseMap refund(String out_trade_no) {

        BaseMap map = new BaseMap();

        List<MedicationOrder> medicationOrders = medicationOrderMapper.selectList(new QueryWrapper<MedicationOrder>().eq("out_trade_no", out_trade_no));
        if (medicationOrders.isEmpty()) {
            throw new JeecgBootException("未查询到订单");
        }

        // 检查所有订单状态，确保都符合退款条件
        for (MedicationOrder order : medicationOrders) {
            if (!order.getStatus().equals("8")) {
                throw new JeecgBootException("存在不符合退款条件的订单");
            }
        }

        // 只对第一个订单执行退款操作
        MedicationOrder firstOrder = medicationOrders.get(0);
        BigDecimal price = new BigDecimal(firstOrder.getTotalPrice());
// 乘以100后，保留0位小数，四舍五入
        BigDecimal multiplied = price.multiply(BigDecimal.valueOf(100))
                .setScale(0, RoundingMode.HALF_UP); // 关键：四舍五入
        Long total = multiplied.longValue();
        String out_refund_no = UUIDGenerator.generate();

        map.put("out_trade_no", out_trade_no);
        map.put("out_refund_no", out_refund_no);
        map.put("total", total);
        map.put("type", "medication");

        map = wechatPaymentService.weChatRefunds(map, firstOrder.getMchId());

        if (map.get("code").equals(200)) {
            // 更新所有订单的状态
            for (MedicationOrder medicationOrder : medicationOrders) {
                medicationOrder.setRefundNumber(out_refund_no);
                medicationOrder.setStatus("5");
                medicationOrder.setRefundTime(DateUtils.getDate());
                medicationOrderMapper.updateById(medicationOrder);
            }

            map.put("status", "5");

            Integer expiry_time = 1000 * expiryTime;

            rabbitMqClient.sendMessage(rabbitConstant.DELAY_QUEUE_ORDER_NAME, map, expiry_time);

           // log.info("订单编号：[{}] 进入退款延迟队列...", out_trade_no);

        } else {
            throw new JeecgBootException("申请退款失败！");
        }
        return map;
    }
    @Override
    public BaseMap refundNotify(HttpServletRequest request,String mchid) {

        BaseMap map = wechatPaymentService.weChatPayRefundsNotify(request,mchid);

        if (!map.get("code").equals(200)) {
            return map;
        }
        checkOrderStatus(map.get("out_trade_no"));

        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<MedicationOrder> checkOrderStatus(String orderId) {

        List<MedicationOrder> medicationOrder=medicationOrderMapper.selectList(new QueryWrapper<MedicationOrder>().eq("out_trade_no", orderId));
        if (medicationOrder.isEmpty()) {
            return null;
        }

        String status = medicationOrder.get(0).getStatus();

        if (status.equals("3") || status.equals("7") || status.equals("8")) {
            return null;
        }
        String refundnum = UUIDGenerator.generate();
     for(MedicationOrder order: medicationOrder){
         order.setStatus("7");
         order.setRefundTime(DateUtils.getDate());
         order.setRefundNumber(refundnum);
         medicationOrderMapper.updateById(order);
     }
        return medicationOrder;
    }
}
